package com.ybkj.daijia.server.service.impl;

import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.serverUtils.UseAllDataUtil;
import com.ybkj.daijia.common.Pager;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.config.PassengerApi;
import com.ybkj.daijia.page.Page;
import com.ybkj.daijia.page.Pageable;
import com.ybkj.daijia.page.domain.Sort;
import com.ybkj.daijia.page.domain.Sort.Direction;
import com.ybkj.daijia.page.impl.PageImpl;
import com.ybkj.daijia.page.impl.PageRequest;
import com.ybkj.daijia.server.mapper.ReceiptMapper;
import com.ybkj.daijia.server.mc.Passenger;
import com.ybkj.daijia.server.model.Receipt;
import com.ybkj.daijia.server.service.ReceiptService;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class DefaultReceiptService implements ReceiptService {

    @Autowired
    private ReceiptMapper receiptMapper;

    @Autowired
    private SettingUtils settingUtils;

    @Autowired
    private PassengerApi passengerApi;

    @Override
    public int save(Receipt receipt) {
        return receiptMapper.insertReceipt(receipt);
    }

    @Override
    public int delete(Long id) {
        return receiptMapper.deleteById(id);
    }

    @Override
    public Receipt findById(Long id) {
        return receiptMapper.selectById(id);
    }

    @Override
    public List<Receipt> findByMemberId(Long id) {
        return receiptMapper.selectByMemberId(id);
    }

    @Override
    public List<Receipt> findAll() {
        return receiptMapper.selectAll();
    }

    @Override
    public int update(Receipt receipt) {
        return receiptMapper.updateReceipt(receipt);
    }

    @Override
    public Page<Receipt> queryAll() {

        Pageable pageable = new PageRequest(Pager.getPage(), Pager.getLimit());

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("offset", Pager.getOffset());
        params.put("size", Pager.getLimit());

        List<Receipt> content = receiptMapper.selectByPage(params);
        long total = receiptMapper.countByPage(params);

        return new PageImpl<Receipt>(content, pageable, total);

    }

    @Override
    public Page<Receipt> findByParam(String param, Date start, Date end) {
        Pageable pageable = new PageRequest(Pager.getPage(), Pager.getLimit());
        Subject currentUser = SecurityUtils.getSubject();
        Map<String, Object> params = new HashMap<String, Object>();

        params.put("offset", Pager.getOffset());
        params.put("size", Pager.getLimit());
        if (StringUtils.isNotBlank(param)) {
            params.put("param", "%" + param + "%");
        } else {
            params.put("param", null);
        }
        if (start != null) {
            params.put("start", start);
        }
        if (end != null) {
            params.put("end", end);
        }

        List<Receipt> content = receiptMapper.selectByParamLike(params);
        for (Receipt receipt : content) {
            receipt.setMemberPhone(UseAllDataUtil.useAllData(receipt.getMemberPhone()));
        }
        long total = receiptMapper.countByPageLike(params);

        return new PageImpl<Receipt>(content, pageable, total);
    }

    @Override
    public Page<Receipt> queryByMemberId(Long id, Integer page, Integer limit) {

        Sort sort = new Sort(Direction.DESC, "id");

        Pageable pageable = new PageRequest(page, limit, sort);

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("mid", id);
        params.put("offset", page * limit);
        params.put("size", limit);

        List<Receipt> content = receiptMapper.selectByMemberPageId(params);
        long total = receiptMapper.countByMemberId(params);

        return new PageImpl<Receipt>(content, pageable, total);
    }

    @Override
    public long findReceiptNumber() {
        return receiptMapper.selectReceiptNumber();
    }

    @Transactional(rollbackFor = Exception.class)
    public Result<Receipt> createReceipt(Passenger passenger, Receipt receipt) {
        Result<Receipt> result = passengerApi
            .createReceipt(passenger, receipt.getMoney(), settingUtils.get());

        if (result.isSuccess()) {
            receiptMapper.insertReceipt(receipt);
        }

        return result;

    }

    @Transactional(rollbackFor = Exception.class)
    public Result<Receipt> delete(Passenger passenger, Receipt receipt) {
        BigDecimal receiptMoney = receipt.getMoney().multiply(new BigDecimal(-1));
        Result<Receipt> result = passengerApi
            .createReceipt(passenger, receiptMoney, settingUtils.get());

        if (result.isSuccess()) {
            receiptMapper.deleteById(receipt.getId());
        }

        return result;
    }

    @Override
    public Page<Receipt> findAllByParam(String name, String number, String phone, Date start,
        Date end) {
        Pageable pageable = new PageRequest(Pager.getPage(), Pager.getLimit());
        Subject currentUser = SecurityUtils.getSubject();
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("offset", Pager.getOffset());
        params.put("size", Pager.getLimit());
        if (StringUtils.isNotBlank(name)) {
            params.put("name", "%" + name + "%");
        } else {
            params.put("name", null);
        }
        if (StringUtils.isNotBlank(number)) {
            params.put("number", "%" + number + "%");
        } else {
            params.put("number", null);
        }
        if (StringUtils.isNotBlank(phone)) {
            params.put("phone", "%" + phone + "%");
        } else {
            params.put("phone", null);
        }
        if (start != null) {
            params.put("start", start);
        }
        if (end != null) {
            params.put("end", end);
        }
        List<Receipt> content = receiptMapper.selectAllByParamLike(params);
        for (Receipt receipt : content) {
            receipt.setMemberPhone(UseAllDataUtil.useAllData(receipt.getMemberPhone()));
        }
        long total = receiptMapper.countAllByPageLike(params);

        return new PageImpl<Receipt>(content, pageable, total);
    }

}